#include "cpu-scheduling.h"
void initQueue(Queue *q) {
    q->head = q->tail = NULL;
}

int isEmpty(Queue *q) {
    return q->head == NULL;
}

/*优先级高的先入队*/
void enqueue_priority_first(Queue *q, PCB *pcb) {
    PCB* node = (PCB*)malloc(sizeof(PCB));
    memcpy(node, pcb, sizeof(PCB));
    if (q->tail) {
        //找到第一个优先级不高于node的位置
        PCB** curr = &q->head;
        while ((*curr) && (*curr)->priority < node->priority)
        {
            curr=&(*curr)->next;
        }
        //插入
        node->next = (*curr);
        *curr = node;
    } else {
        node->next = NULL;
        q->head = q->tail = node;
    }
}

/*到达时间早的先入队*/
void enqueue_releasetime_first(Queue *q, PCB *pcb) {
    PCB* node = (PCB*)malloc(sizeof(PCB));
    memcpy(node, pcb, sizeof(PCB));
    if (q->tail) {
        //找到第一个到达时间不早于node的位置
        PCB** curr = &q->head;
        while ((*curr) && (*curr)->releaseTime < node->releaseTime)
        {
            curr=&(*curr)->next;
        }
        //插入
        node->next = (*curr);
        *curr = node;
    } else {
        node->next = NULL;
        q->head = q->tail = node;
    }
}

/*到达剩余时间短的先入队*/
void enqueue_lefttime_first(Queue *q, PCB *pcb) {
    PCB* node = (PCB*)malloc(sizeof(PCB));
    memcpy(node, pcb, sizeof(PCB));
    if (q->tail) {
        //找到第一个到达时间不早于node的位置
        PCB** curr = &q->head;
        //left time = cut time - executed time
        while ((*curr) && (*curr)->cpuTime - (*curr)->executedTime < node->cpuTime - node->executedTime)
        {
            curr=&(*curr)->next;
        }
        //插入
        node->next = (*curr);
        *curr = node;
    } else {
        node->next = NULL;
        q->head = q->tail = node;
    }
}
PCB* dequeue(Queue *q) {
    if (isEmpty(q)) return NULL;
    PCB *temp = q->head;
    q->head = q->head->next;
    if (!q->head) q->tail = NULL;
    return temp;
}

PCB* readTasks(const char *filename) {
    FILE *file = fopen(filename, "r");
    if (!file) {
        perror("Failed to open task file");
        exit(1);
    }

    PCB *head = NULL, *tail = NULL;
    int procID, releaseTime, priority, cpuTime;

    while (fscanf(file, "%d %d %d %d", &procID, &releaseTime, &priority, &cpuTime) == 4) {
        PCB *pcb = (PCB*)malloc(sizeof(PCB));
        pcb->procID = procID;
        pcb->releaseTime = releaseTime;
        pcb->priority = priority;
        pcb->cpuTime = cpuTime;
        pcb->executedTime = 0;
        pcb->state = 0; // 默认为就绪状态
        pcb->next = NULL;

        if (tail) {
            tail->next = pcb;
            tail = pcb;
        } else {
            head = tail = pcb;
        }
    }
    fclose(file);
    return head;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <task.txt> <algorithm>\n", argv[0]);
        return 1;
    }

    PCB *tasks = readTasks(argv[1]);
    char *algorithm = argv[2];

    if (strcmp(algorithm, "sjf") == 0) {
        sjf(tasks);
    } else if (strcmp(algorithm, "psjf") == 0) {
        psjf(tasks);
    } else if (strcmp(algorithm, "pprio") == 0) {
        pprio(tasks);
    } else if (strcmp(algorithm, "prio") == 0) {
        prio(tasks);
    } else {
        fprintf(stderr, "Unknown algorithm: %s\n", algorithm);
        return 1;
    }

    return 0;
}